package parsing;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public class PeopleParser {

	// Persons Map
	public static Map<String, Person> persons;

	// values extracted
	public static int numOfValues;

	/*
	 * gets the path for the TSV file (geoFacts.tsv) parse it while
	 * creating/updating person instances (persons map) and fills category field
	 */
	public static void parsePersonCategory(String path) {
		persons = new HashMap<String, Person>();

		// get file path
		BufferedReader buf = null;
		try {
			buf = new BufferedReader(new FileReader(path));
		} catch (FileNotFoundException e1) {
			// TODO handle errors
			e1.printStackTrace();
		}

		numOfValues = 0;
		Person newPerson;
		String currLine = null;
		try {
			currLine = buf.readLine();
		} catch (IOException e) {
			// TODO handle errors
			e.printStackTrace();
		}
		/* Search For Relevant Persons */
		while (currLine != null) {

			String[] lineParts;
			if (currLine.contains("<playsFor>")
					|| currLine.contains("<actedIn>")
					|| currLine.contains("<wordnet_vocal_music_107282006>")) {
				// if(i>100){ break;}
				// separates the line according to all white spaces
				currLine = currLine.replaceAll(">|<", "");
				currLine = currLine.replaceAll("_", " ");
				lineParts = currLine.split("\t");

				if (!persons.containsKey(lineParts[1])) { /* person not exists */
					newPerson = new Person(lineParts[1]);
					persons.put(newPerson.getName(), newPerson);
				} else { /* person already exists */
					newPerson = persons.get(lineParts[1]);
				}

				// add relevant categories (at least one)
				if (lineParts[2].equals("playsFor")
						&& !newPerson.isOnCategory(1)) {
					newPerson.addCategory(1);
				} else if (lineParts[2].equals("actedIn")
						&& !newPerson.isOnCategory(2)) {
					newPerson.addCategory(2);
				} else if (lineParts[3].equals("wordnet vocal music 107282006")
						&& !newPerson.isOnCategory(3))/* hasMusicalRole */{
					newPerson.addCategory(3);
				}

				numOfValues++;

				// DEBUG

				/*
				 * if (newPerson.categories.size() > 1){
				 * System.out.println(persons.get(newPerson.name).toString()); }
				 */

			}
			try {
				currLine = buf.readLine();
			} catch (IOException e) {
				// TODO error handling
				e.printStackTrace();
			}
		}

		// DEBUG
		// System.out.println("found: " + numOfValues);
		// System.out.println("uniques: " + persons.size());

		try {
			buf.close();
		} catch (IOException e) {
			// TODO handle errors
			e.printStackTrace();
		}

	}

	/*
	 * Gets the path of the TSV file (geoFacts.tsv) looks for all mapped persons
	 * birth and death places and updates the map
	 */
	public static void parsePersonAttr(String path) {

		// get file path
		BufferedReader buf = null;
		try {
			buf = new BufferedReader(new FileReader(path));
		} catch (FileNotFoundException e1) {
			// TODO handle errors
			e1.printStackTrace();
		}
		// read from file
		Person currPerson;
		String currLine = null;
		try {
			currLine = buf.readLine();
		} catch (IOException e) {
			// TODO handle errors
			e.printStackTrace();
		}
		int i = 0;
		while (currLine != null) {

			String[] lineParts;
			if (currLine.contains("<diedIn>")
					|| currLine.contains("<wasBornIn>")) {

				// separates the line according to all white spaces
				currLine = currLine.replaceAll(">|<", "");
				lineParts = currLine.split("\\s+");
				lineParts[1] = lineParts[1].replaceAll("_", " ");
				if (persons.containsKey(lineParts[1])) { /* person exists */
					i++;
					// get relevant person
					currPerson = persons.get(lineParts[1]);
					if (lineParts[2].equals("diedIn")) {
						lineParts[3]= parserCityName(lineParts[3]);
						currPerson.setDeathCity(lineParts[3]);

						// currPerson.identifyDeathCity();//search for the city
						// in cities

					} else { /* lineParts[2].equals("wasBornIn") */

						lineParts[3]= parserCityName(lineParts[3]);
						currPerson.setBirthCity(lineParts[3]);
						// currPerson.identifyBirthCity(); //search for the city
						// in cities
					}
					// DEBUG:
					// System.out.println(currPerson.toString());
				}

			}

			try {
				currLine = buf.readLine();
			} catch (IOException e) {
				// TODO error handling
				e.printStackTrace();
			}
		}

		try {
			buf.close();
		} catch (IOException e) {
			// TODO handle errors
			e.printStackTrace();
		}
		// DEBUG
		// System.out.println(i);
	}

	/*
	 * Prints all persons data into text file (import to mySQL)
	 */
	public static void printPersonsToFile(String outputPersonsPath,
			String OutputCategoriesPath) {

		// Create output file
		File file1 = new File(outputPersonsPath);
		File file2 = new File(OutputCategoriesPath);
		try {
			file1.createNewFile();
			file2.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		FileWriter personFileBf = null;
		FileWriter categoriesFileBf = null;
		try {
			personFileBf = new FileWriter(file1.getAbsoluteFile());
			categoriesFileBf = new FileWriter(file2.getAbsoluteFile());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BufferedWriter personBw = new BufferedWriter(personFileBf);
		BufferedWriter categoryBw = new BufferedWriter(categoriesFileBf);

		Person currPerson;
		// write map into file
		for (Map.Entry<String, Person> entry : persons.entrySet()) {
			currPerson = entry.getValue();
			try {
				personBw.write(entry.getValue().getId() + "\t"
						+ currPerson.getName() + "\t");
				if (currPerson.getBirthCity() != null) {
					personBw.write(currPerson.getBirthCity() + "\t");
				}
				if (currPerson.getDeathCity() != null) {
					personBw.write(currPerson.getDeathCity() + "\t");
				}
				personBw.write("\n");

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (int categoryID : currPerson.getCategories()) {
				try {

					categoryBw.write(currPerson.getId() + "\t" + categoryID
							+ "\n");

				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

		// close all buffers
		try {
			categoriesFileBf.close();
			personBw.close();
			personFileBf.close();
			categoriesFileBf.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static String parserCityName(String city) {
		int index;
		/* option 1- a city that starts with St. */
		if ((city.contains("St.")) || (city.contains("Sault"))
				|| (city.contains("D.C."))) {
			if (city.contains(",_")) {
				 index = city.indexOf(",");
				city = city.substring(0, index);
			}
		} else {
			if (city.contains("._")) {
				 index = city.indexOf(".");
				city = city.substring(0, index);
			}else if(city.contains(",_")){
				 index = city.indexOf(",");
				city = city.substring(0, index);
			}
		}
		if (city.contains("New_York_City")){
			 index=city.indexOf("C");
			 city=city.substring(0,index);
		}
		city = city.replaceAll("_", " ");

		return city;

	}
}
